//
// File:	BaseEntity.hpp
// Author:	Thomas TISSOT-DUPONT
// Login:	<thomas.tissotdupont@free.fr>
//
// Create:	27/01/2010 at 17:55:05
// Purpose:	
//
#ifndef BASEENTITY_HPP
#define BASEENTITY_HPP

#include <SFML/Graphics.hpp>		//TODO: replace every reference to sf::* types by basic types
#include "SDKBase.hpp"
#include "Event.hpp"
#include "IEntity.hpp"
#include "EntityDataMap.hpp"

//------------------------------------------------------------------
// Helpers Macros
//------------------------------------------------------------------
#define DECLARE_DATAMAP_FIELD(name, var, def)		m_dataMap.AddField(name, var, def)
#define LINK_ENTITY_TO_CLASS(name, cppname)			GlobalVariables::FactoryManager::Get().GetEntityFactory()->RegisterEntityClass(#name, &cppname::Create)
#define DECLARE_ENTITY(cppname)						public:															\
														static IEntity *Create(const std::string &classname)		\
														{															\
															IEntity *pEntity = new cppname();						\
															if (pEntity) pEntity->SetClassname(classname);			\
															return pEntity;											\
														}


//------------------------------------------------------------------
// BaseEntity Class
//------------------------------------------------------------------
class BaseEntity : public IEntity
{
	DECLARE_ENTITY(BaseEntity);

protected:
						BaseEntity();
						~BaseEntity();

public events:
						Event<void (BaseEntity *)>		OnCreated;
						Event<void (BaseEntity *)>		OnUpdated;
						Event<void (BaseEntity *)>		OnRemoved;

protected:
	void				OnCreate();
	void				OnDestroy();
	void				OnCreateDataMap();

public:
	void				WriteDataMapVariable(const std::string &, const Variant &);

public:
	void				Render();
	void				Update();

public:
	IAnimating			*GetAnimating() const;

public:
	void				FollowEntity(IEntity *);
	IEntity				*GetFollowingEntity() const;
	void				SetFollowOffsetX(float);
	void				SetFollowOffsetY(float);
	void				SetFollowOffsetCenterX(float);
	void				SetFollowOffsetCenterY(float);
	float				GetFollowOffsetX() const;
	float				GetFollowOffsetY() const;

public:
	const std::string	&GetClassname() const;

private:
	void				SetClassname(const std::string &name);

public:
	bool				LoadFromFile(const std::string &fileName);

public:
	static BaseEntity	*CreateEntityByName(const std::string &name);

public:
	ISound				*EmitSound(const std::string &filename, bool bRemoveOnDeath = false, bool bFollow = false, bool bSpatialization = true);
private:
	void				UpdateFollowingSound(ISound *);

public:
	bool				IsRemoved() const;
	void				Remove();

public:
	void				SetRenderGroup(RenderGroup renderGroup);
	RenderGroup			GetRenderGroup() const;

public:
	void				SetX(float);
	void				SetY(float);
	void				SetWidth(float);
	void				SetHeight(float);
	void				SetCenterX(float);
	void				SetCenterY(float);
	void				SetVelocityX(float);
	void				SetVelocityY(float);
	float				GetX() const;
	float				GetY() const;
	float				GetWidth() const;
	float				GetHeight() const;
	float				GetCenterX() const;
	float				GetCenterY() const;
	float				GetVelocityX() const;
	float				GetVelocityY() const;

protected:
	EntityDataMap		m_dataMap;

private:
	std::string			m_classname;
	bool				m_bRemoved;
	sf::Vector2f		m_vfPosition;
	sf::Vector2f		m_vfFollowOffset;
	sf::Vector2f		m_vfSize;
	sf::Vector2f		m_vfVelocity;
	IEntity				*m_pFollow;
	RenderGroup			m_renderGroup;
	IAnimating			*m_pAnimating;
};

#endif //!BASEENTITY_HPP
